package com.teacher.ellio;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;
import com.teacher.game.framework.animation.Animation;
import com.teacher.game.framework.animation.Frame;
import com.teacher.game.framework.util.BitmapCache;

/**
 * 资源管理器 - 统一管理游戏中的所有资源
 * 包括图片、音效、动画等资源的加载和管理
 */
public class Assets {

    // 音效系统
    private static SoundPool soundPool;
    private static float currentSfxVolume = 1.0f;  // 当前音效音量
    private static float currentBgMusicVolume = 0.5f;  // 当前背景音乐音量
    private static boolean soundEnabled = true;  // 音效开关
    
    // 音效播放控制
    private static long lastSoundPlayTime = 0;  // 上次播放音效的时间
    private static int lastSoundId = -1;  // 上次播放的音效ID
    private static final long SOUND_COOLDOWN = 300;  // 音效冷却时间(毫秒)
    
    // UI界面资源
    public static Bitmap welcome, start, startDown, score, scoreDown;
    
    // 游戏场景资源
    public static Bitmap grass, cloud1, cloud2, block;
    
    // 角色动画资源
    public static Bitmap jump, duck;
    
    // 音效ID
    public static int startId, jumpSoundId, hitSoundId, bgMusicId;
    
    // 背景音乐流ID（用于控制）
    private static int bgMusicStreamId = 0;
    
    // 动画对象
    public static Animation runAnim, jumpAnim, duckAnim;
    
    // 游戏颜色
    public static int skyBlue;

    /**
     * 加载所有游戏资源
     */
    public static void load() {
        initSoundPool();
        loadImages();
        loadSounds();
        loadAnimations();
        initColors();
    }
    
    /**
     * 初始化音效池
     */
    private static void initSoundPool() {
        if (soundPool == null) {
            // 优化的SoundPool配置
            soundPool = new SoundPool.Builder()
                .setMaxStreams(15)  // 增加最大流数量，支持更多同时播放的音效
                .build();
            
            // 设置加载完成监听器
            soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
                @Override
                public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                    if (status == 0) {
                        Log.d("Assets", "音效加载完成，ID: " + sampleId);
                    } else {
                        Log.e("Assets", "音效加载失败，ID: " + sampleId);
                    }
                }
            });
        }
    }
    
    /**
     * 加载图片资源
     */
    private static void loadImages() {
        // UI界面资源
        welcome = loadBitmap("welcome.png");
        start = loadBitmap("start_button.png");
        startDown = loadBitmap("start_button_down.png");
        score = loadBitmap("score_button.png");
        scoreDown = loadBitmap("score_button_down.png");
        
        // 游戏场景资源
        grass = loadBitmap("grass.png");
        cloud1 = loadBitmap("cloud1.png");
        cloud2 = loadBitmap("cloud2.png");
        block = loadBitmap("block.png");
        
        // 角色动作资源
        jump = loadBitmap("jump.png");
        duck = loadBitmap("duck.png");
    }
    
    /**
     * 加载音效资源
     */
    private static void loadSounds() {
        startId = loadSound("start.mp3");
        jumpSoundId = loadSound("onjump.wav");
        hitSoundId = loadSound("hit.wav");
        bgMusicId = loadSound("bgmusic.mp3");
    }
    
    /**
     * 加载动画资源
     */
    private static void loadAnimations() {
        // 跑步动画（多帧）
        Frame f1 = new Frame(loadBitmap("run_anim1.png"), 0.1f);
        Frame f2 = new Frame(loadBitmap("run_anim2.png"), 0.1f);
        Frame f3 = new Frame(loadBitmap("run_anim3.png"), 0.1f);
        Frame f4 = new Frame(loadBitmap("run_anim4.png"), 0.1f);
        Frame f5 = new Frame(loadBitmap("run_anim5.png"), 0.1f);
        runAnim = new Animation(f1, f2, f3, f4, f5, f3, f2);
        
        // 跳跃动画（单帧）
        Frame jumpFrame = new Frame(jump, 1.0f);
        jumpAnim = new Animation(jumpFrame);
        
        // 下蹲动画（单帧）
        Frame duckFrame = new Frame(duck, 1.0f);
        duckAnim = new Animation(duckFrame);
    }
    
    /**
     * 初始化颜色常量
     */
    private static void initColors() {
        skyBlue = Color.rgb(208, 244, 247);
    }

    /**
     * 加载音效文件
     * @param filename 音效文件名
     * @return 音效ID
     */
    private static int loadSound(String filename) {
        int soundId = 0;
        if (soundPool == null) {
            Log.e("Assets", "SoundPool未初始化");
            return soundId;
        }
        
        try {
            soundId = soundPool.load(GameMainActivity.assets.openFd(filename), 1);
            Log.d("Assets", "音效加载成功: " + filename);
        } catch (Exception e) {
            Log.e("Assets", "音效加载失败: " + filename, e);
            throw new RuntimeException("无法加载音效文件: " + filename, e);
        }
        return soundId;
    }

    /**
     * 播放音效（带防重复播放机制）
     * @param soundId 音效ID
     */
    public static void playSound(int soundId) {
        if (soundPool != null && soundId != 0 && soundEnabled) {
            long currentTime = System.currentTimeMillis();
            
            // 防重复播放：如果是同一音效且在冷却时间内，则不播放
            if (soundId == lastSoundId && (currentTime - lastSoundPlayTime) < SOUND_COOLDOWN) {
                Log.d("Assets", "音效在冷却期内，跳过播放: " + soundId);
                return;
            }
            
            soundPool.play(soundId, currentSfxVolume, currentSfxVolume, 1, 0, 1.0f);
            lastSoundPlayTime = currentTime;
            lastSoundId = soundId;
            Log.d("Assets", "播放音效: " + soundId);
        }
    }
    
    /**
     * 播放音效（自定义音量，带防重复播放机制）
     * @param soundId 音效ID
     * @param volume 音量 (0.0-1.0)
     */
    public static void playSound(int soundId, float volume) {
        if (soundPool != null && soundId != 0 && soundEnabled) {
            long currentTime = System.currentTimeMillis();
            
            // 防重复播放：如果是同一音效且在冷却时间内，则不播放
            if (soundId == lastSoundId && (currentTime - lastSoundPlayTime) < SOUND_COOLDOWN) {
                Log.d("Assets", "音效在冷却期内，跳过播放: " + soundId);
                return;
            }
            
            soundPool.play(soundId, volume, volume, 1, 0, 1.0f);
            lastSoundPlayTime = currentTime;
            lastSoundId = soundId;
            Log.d("Assets", "播放音效(自定义音量): " + soundId + ", 音量: " + volume);
        }
    }
    
    /**
     * 播放背景音乐（循环）
     */
    public static void playBgMusic() {
        if (soundPool != null && bgMusicId != 0 && soundEnabled) {
            // 停止之前的背景音乐
            stopBgMusic();
            // 播放新的背景音乐
            bgMusicStreamId = soundPool.play(bgMusicId, currentBgMusicVolume, currentBgMusicVolume, 2, -1, 1.0f);
            Log.d("Assets", "背景音乐开始播放，流ID: " + bgMusicStreamId);
        }
    }
    
    /**
     * 停止背景音乐
     */
    public static void stopBgMusic() {
        if (soundPool != null && bgMusicStreamId != 0) {
            soundPool.stop(bgMusicStreamId);
            bgMusicStreamId = 0;
            Log.d("Assets", "背景音乐已停止");
        }
    }
    
    /**
     * 设置音效音量
     * @param volume 音量（0.0-1.0）
     */
    public static void setSfxVolume(float volume) {
        currentSfxVolume = Math.max(0.0f, Math.min(1.0f, volume));
        Log.d("Assets", "音效音量设置为: " + currentSfxVolume);
    }
    
    /**
     * 设置背景音乐音量
     * @param volume 音量（0.0-1.0）
     */
    public static void setBgMusicVolume(float volume) {
        currentBgMusicVolume = Math.max(0.0f, Math.min(1.0f, volume));
        // 如果背景音乐正在播放，立即应用新音量
        if (bgMusicStreamId != 0) {
            soundPool.setVolume(bgMusicStreamId, currentBgMusicVolume, currentBgMusicVolume);
        }
        Log.d("Assets", "背景音乐音量设置为: " + currentBgMusicVolume);
    }
    
    /**
     * 设置音效开关
     * @param enabled 是否启用音效
     */
    public static void setSoundEnabled(boolean enabled) {
        soundEnabled = enabled;
        if (!enabled) {
            stopBgMusic();
        }
        Log.d("Assets", "音效" + (enabled ? "开启" : "关闭"));
    }
    
    /**
     * 获取当前音效音量
     * @return 音效音量 (0.0-1.0)
     */
    public static float getSfxVolume() {
        return currentSfxVolume;
    }
    
    /**
     * 获取当前背景音乐音量
     * @return 背景音乐音量 (0.0-1.0)  
     */
    public static float getBgMusicVolume() {
        return currentBgMusicVolume;
    }
    
    /**
     * 检查音效是否启用
     * @return 音效是否启用
     */
    public static boolean isSoundEnabled() {
        return soundEnabled;
    }
    
    /**
     * 释放音效资源
     */
    public static void release() {
        if (soundPool != null) {
            stopBgMusic();
            soundPool.release();
            soundPool = null;
            Log.d("Assets", "音效资源已释放");
        }
    }

    /**
     * 加载图片文件
     * @param filename 图片文件名
     * @return Bitmap对象
     */
    private static Bitmap loadBitmap(String filename) {
        // 先尝试从缓存获取
        BitmapCache cache = BitmapCache.getInstance();
        Bitmap bitmap = cache.getBitmap(filename);
        
        if (bitmap != null) {
            Log.d("Assets", "从缓存获取图片: " + filename);
            return bitmap;
        }
        
        // 缓存中没有，从文件加载
        try {
            bitmap = BitmapFactory.decodeStream(GameMainActivity.assets.open(filename));
            if (bitmap == null) {
                Log.e("Assets", "位图解码失败: " + filename);
                throw new RuntimeException("无法解码图片资源: " + filename);
            }
            
            // 加载成功，放入缓存
            cache.putBitmap(filename, bitmap);
            Log.d("Assets", "图片加载并缓存成功: " + filename + " (" + bitmap.getWidth() + "x" + bitmap.getHeight() + ")");
            
        } catch (Exception e) {
            Log.e("Assets", "图片加载失败: " + filename, e);
            throw new RuntimeException("无法加载图片资源: " + filename, e);
        }
        return bitmap;
    }
    
    /**
     * 释放资源
     */
    public static void releaseAll() {
        // 释放音效资源
        release();
        
        // 释放Bitmap缓存
        BitmapCache.getInstance().clearCache();
        Log.d("Assets", "所有资源已释放");
    }
    
    /**
     * 获取缓存统计信息
     * @return 缓存统计字符串
     */
    public static String getCacheStats() {
        return BitmapCache.getInstance().getCacheStats();
    }
    
    /**
     * 获取缓存命中率
     * @return 命中率（0-100）
     */
    public static int getCacheHitRate() {
        return BitmapCache.getInstance().getCacheHitRate();
    }
}
